package com.freight.tws.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.freight.common.core.constant.DictConstants;
import com.freight.common.core.constant.WebsocketConstants;
import com.freight.common.core.exception.ServiceException;
import com.freight.common.core.utils.DateUtils;
import com.freight.common.core.utils.NoUtils;
import com.freight.common.core.utils.SecurityUtils;
import com.freight.common.core.utils.StringUtils;
import com.freight.common.core.utils.bean.BeanUtils;
import com.freight.tws.api.domain.*;
import com.freight.tws.domain.TwsCompany;
import com.freight.tws.domain.TwsUseRecord;
import com.freight.tws.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.freight.common.core.web.controller.BaseServiceImpl;
import com.freight.tws.mapper.OrderMapper;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 订单Service业务层处理
 *
 * @author ruoyi
 * @date 2022-02-08
 */
@Service
public class OrderServiceImpl extends BaseServiceImpl<OrderMapper, Order> implements IOrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private ITwsUseRecordService useRecordService;

    @Autowired
    private IOrderGoodsService orderGoodsService;

    @Autowired
    private ITwsCompanyService twsCompanyService;

    @Autowired
    private ITwsNoticeService twsNoticeService;

    /**
     * 获取订单详细信息
     */
    @Override
    public Order getInfo(Long id) {
        Order order = orderMapper.selectById(id);
        if(order == null) {
            throw new ServiceException("订单不存在");
        }
        // 查询货物信息
        List<OrderGoods> orderGoods = orderGoodsService.list(new LambdaQueryWrapper<OrderGoods>()
                .eq(OrderGoods::getOrderId, order.getId()));
        order.setOrderGoods(orderGoods);
        return order;
    }

    /**
     * 新增订单
     * @param order
     * @return
     */
    @Override
    @Transactional
    public boolean add(Order order) {
        // 货物必填
        if(order.getOrderGoods().size() == 0) {
            throw new ServiceException("请填写货物");
        }
        // 查询登录人的物流公司id
        TwsCompany company = twsCompanyService.getById(SecurityUtils.getTenantId());
        if(company == null) {
            throw new ServiceException("操作失败");
        }
        // 完善订单信息
        order.setSerialNumber("0000");  // 分段分单号
        order.setVehicleAmount(1);  // 运输总车辆数
        order.setTransportTypeCode(1);   // 运输组织类型 - 1公路运输
        order.setBusinessTypeCode("1002996");    // 业务类型 - 1002996干线普货运输
        order.setPolicyNumber("none");  // 保险单号 - 无
        order.setInsuranceCompanyCode("none");    // 保险公司 - 无
//        order.setActualCarrierName(company.getCompanyName());   // 实际承运人名称
        order.setActualCarrierBusinessLicense(company.getLicenseNo());    // 实际承运人道路运输经营许可证号
//        order.setActualCarrierId(company.getTaxNo()); // 实际承运人统一社会信用代码或证件号码
        order.setIsReceipt("0");  // 是否回单 - 0否
        order.setStatus(DictConstants.ORDER_STATUS.DFC.getKey());   // 订单状态
        order.setIsSendToPro(DictConstants.IS_SEND_TO_PRO.WSC.getKey());  // 是否已上传 - 0未上传
        order.setIsPay("0");  // 是否支付 - 0否
        order.setIsBill("0");  // 是否开了发票 - 0否
        order.setCompanyName(company.getCompanyName()); // 物流公司名称

        // 每个司机都生成同样的订单
        if(order.getDrivers().size() > 0) {
            for (Driver driver : order.getDrivers()) {
                Order o = new Order();
                BeanUtils.copyBeanProp(o, order);
                o.setDriverId(driver.getId());
                o.setDriverLicense(driver.getDrivingLicense());
                o.setDriverName(driver.getDriverName());
                o.setDriverPhone(driver.getTelephone());
                o.setActualCarrierName(driver.getDriverName());   // 实际承运人名称（要与支付收款人一致，所以填司机名）
                o.setActualCarrierId(driver.getDrivingLicense()); // 实际承运人统一社会信用代码或证件号码
                this.saves(o);
            }
        } else {
            this.saves(order);
        }
        return true;
    }

    /**
     * 修改订单
     * @param order
     * @return
     */
    @Override
    @Transactional
    public boolean edit(Order order) {
        Order dbOrder = orderMapper.selectById(order.getId());
        if(dbOrder == null) {
            throw new ServiceException("订单不存在");
        }

        //操作日志
        TwsUseRecord useRecord = new TwsUseRecord();
        useRecord.setOrderId(order.getId());
        useRecord.setOperateContent(order.getRecordContent());
        useRecord.setOperateTime(new Date());
        useRecord.setOperator(SecurityUtils.getUsername());
        useRecordService.save(useRecord);
        return this.updateById(order);
    }

    /**
     * 删除订单
     * @param id
     * @return
     */
    @Override
    public boolean delete(Long id) {
        Order order = orderMapper.selectById(id);
        if(order == null) {
            throw new ServiceException("订单不存在");
        }
        if(!DictConstants.ORDER_STATUS.DFC.getKey().equals(order.getStatus())) {
            throw new ServiceException("订单正在运输中或已完成,无法删除");
        }
        return this.removeById(order);
    }

    /**
     * APP端发车
     * @param order
     * @return
     */
    @Override
    @Transactional
    public boolean appStartOrder(Order order) {
        Order order1 = orderMapper.selectById(order.getId());
        if(order1 == null || !DictConstants.ORDER_STATUS.DFC.getKey().equals(order1.getStatus())) {
            throw new ServiceException("订单失效");
        }
        // 查询是否有未完成的订单
        LambdaQueryWrapper<Order> lqw = new LambdaQueryWrapper<>();
        lqw.in(Order::getStatus, Arrays.asList(DictConstants.ORDER_STATUS.YSZ.getKey()));
        lqw.eq(Order::getDriverId, SecurityUtils.getUserId());
        int count = orderMapper.selectCount(lqw);
        if(count > 0) {
            throw new ServiceException("您当前有未完成的订单");
        }
        order1.setDespatchActualDateTime(new Date());   // 发货时间
        order1.setStatus(DictConstants.ORDER_STATUS.YSZ.getKey());   // 订单状态: 待发车 -> 运输中
        // 车辆信息
        order1.setVehicleId(order.getVehicleId());
        order1.setVehicleNumber(order.getVehicleNumber());
        order1.setVehiclePlateColorCode(order.getVehiclePlateColorCode());
        if(order.getTrailerVehicleId() != null) {
            order1.setTrailerVehicleId(order.getTrailerVehicleId());
            order1.setTrailerVehiclePlateNumber(order.getTrailerVehiclePlateNumber());
            order1.setTrailerVehiclePlateColorCode(order.getTrailerVehiclePlateColorCode());
        }

        //操作日志
        TwsUseRecord useRecord = new TwsUseRecord();
        useRecord.setOrderId(order.getId());
        useRecord.setOperateContent("司机发车");
        useRecord.setOperateTime(order1.getDespatchActualDateTime());
        useRecord.setOperator(SecurityUtils.getUsername());
        useRecordService.save(useRecord);

        return this.updateById(order1);
    }

    /**
     * APP端回单
     * @param order
     * @return
     */
    @Override
    @Transactional
    public boolean appBackOrder(Order order) {
        if(StringUtils.isBlank(order.getBackImages())) {
            throw new ServiceException("请上传回单");
        }
        Order selectById = orderMapper.selectById(order.getId());
        if(selectById == null) {
            throw new ServiceException("无此订单");
        }
        selectById.setIsReceipt("1");  // 是否回单 - 1是
        selectById.setBackImages(order.getBackImages()); // 回单照片
        selectById.setGoodsReceiptDateTime(new Date());  // 收货时间
        selectById.setStatus(DictConstants.ORDER_STATUS.YWC.getKey());   // 订单状态: 运输中 -> 已完成

        // 通知物流公司，订单已完成
        String userName = twsCompanyService.getUserNameByCompanyId(Long.valueOf(selectById.getTenantId()));
        if(StringUtils.isNotBlank(userName)) {
            // 保存到业务公告消息表（包含websocket通知）
            twsNoticeService.newTwsNotice(userName, WebsocketConstants.TWS_NOTICE_TYPE.ORDER_FINISH.getKey(), WebsocketConstants.TWS_NOTICE_TYPE.ORDER_FINISH.getName().replace("#", selectById.getShippingNoteNumber()));
        }

        //操作日志
        TwsUseRecord useRecord = new TwsUseRecord();
        useRecord.setOrderId(order.getId());
        useRecord.setOperateContent("司机送达上传回单");
        useRecord.setOperateTime(order.getGoodsReceiptDateTime());
        useRecord.setOperator(SecurityUtils.getUsername());
        useRecordService.save(useRecord);

        return this.updateById(selectById);
    }

    /**
     * 评价
     * @param order
     * @return
     */
    @Override
    public boolean starOrder(Order order) {
        Order o = orderMapper.selectById(order.getId());
        if(StringUtils.isNull(o)) {
            throw new ServiceException("订单不存在");
        }
        if(!DictConstants.ORDER_STATUS.YWC.getKey().equals(o.getStatus())) {
            throw new ServiceException("订单未完成，无法评价");
        }
        return this.updateById(order);
    }

    /**
     * 首页折线图
     */
    @Override
    public List<Map<String, String>> orderLineChartCount(String date) {
        if(StringUtils.isEmpty(date)) {
            date = DateUtils.getDate();
        }
        return orderMapper.orderLineChartCount(date, DictConstants.DELETE_BASE.OK.getKey());
    }

    /**
     * 保存订单和货物
     * @param order
     */
    private void saves(Order order) {
        order.setOriginalDocumentNumber("SY" + NoUtils.randomNo()); // 上游企业委托运输单号
        order.setShippingNoteNumber("YD" + NoUtils.randomNo()); // 订单号
        // 先保存订单
        this.save(order);
        // 保存货物
        String createBy = String.valueOf(SecurityUtils.getUserId());
        Date date = new Date();
        for (OrderGoods orderGood : order.getOrderGoods()) {
            orderGood.setId(null);
            orderGood.setOrderId(order.getId());
            orderGood.setOrderNo(order.getShippingNoteNumber());
            orderGood.setCreateBy(createBy);
            orderGood.setCreateTime(date);
            orderGood.setDelFlag(DictConstants.DELETE_BASE.OK.getKey());
        }
        orderGoodsService.saveBatch(order.getOrderGoods());

        TwsCompany company = twsCompanyService.getById(SecurityUtils.getTenantId());
        TwsUseRecord useRecord = new TwsUseRecord();
        useRecord.setOrderId(order.getId());
        useRecord.setOperateContent("货主下单");
        useRecord.setOperateTime(order.getCreateTime());
        useRecord.setOperator(company.getCompanyName());
        useRecordService.save(useRecord);
    }

    /**
     * 根据开票ID获取相关订单
     * @param id
     * @return
     */
    @Override
    public List<Order> getBillOrder(String id) {
        return orderMapper.getBillOrder(id);
    }

    /**
     * 根据支付ID获取相关订单
     * @param id
     * @return
     */
    @Override
    public List<Order> getPayOrder(String id) {
        return orderMapper.getPayOrder(id);
    }
}
